module xml_data_readxsd
    use READ_XML_PRIMITIVES
    use WRITE_XML_PRIMITIVES
    use XMLPARSE
    implicit none
    integer, private :: lurep_
    logical, private :: strict_

    type xs_annotation
        character(len=1), dimension(:), pointer :: documentation => null()
    end type xs_annotation

    type xs_component
        character(len=60) :: ref
        character(len=20) :: minOccurs = "1"
        character(len=20) :: maxOccurs = "1"
    end type xs_component

    type xs_attribute
        character(len=40) :: name
        character(len=40) :: type
        character(len=40) :: use
    end type xs_attribute

    type xs_restriction
        character(len=40) :: base
        character(len=40), dimension(:), pointer :: enumeration => null()
        integer :: minInclusive
        integer :: maxInclusive
        character(len=40) :: pattern
    end type xs_restriction
    type(xs_restriction) :: dummy_xs_restriction

    type xs_union
        character(len=80) :: memberTypes
    end type xs_union

    type xs_extension
        type(xs_attribute), dimension(:), pointer :: attribute => null()
    end type xs_extension

    type xs_simpleContent
        type(xs_extension) :: extension
    end type xs_simpleContent

    type xs_sequence
        type(xs_component), dimension(:), pointer :: component => null()
    end type xs_sequence

    type xs_all
        type(xs_component), dimension(:), pointer :: component => null()
    end type xs_all

    type xs_choice
        type(xs_component), dimension(:), pointer :: component => null()
    end type xs_choice

    type xs_complexType
        type(xs_all) :: all
        type(xs_sequence) :: sequence
        type(xs_choice) :: choice
        type(xs_simpleContent) :: simpleContent
    end type xs_complexType
    type(xs_complexType) :: dummy_xs_complexType

    type xs_simpleType
        character(len=60) :: name
        type(xs_restriction) :: restriction
        type(xs_union) :: union
    end type xs_simpleType
    type(xs_simpleType) :: dummy_xs_simpleType

    type xs_element
        logical :: written = .false.
        logical :: simple = .false.
        logical :: referred = .false.
        character(len=60) :: name
        character(len=60) :: type
        logical :: nillable
        type(xs_annotation) :: annotation
        type(xs_complexType) :: complexType
        type(xs_simpleType) :: simpleType
        type(xs_attribute), dimension(:), pointer :: attribute => null()
    end type xs_element
    type(xs_element), dimension(:), pointer :: element => null()
    type(xs_simpleType), dimension(:), pointer :: simple_element => null()
contains
    subroutine read_xml_type_xs_annotation_array( &
        info, tag, endtag, attribs, noattribs, data, nodata, &
        dvar, has_dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(inout) :: tag
        logical, intent(inout) :: endtag
        character(len=*), dimension(:, :), intent(inout) :: attribs
        integer, intent(inout) :: noattribs
        character(len=*), dimension(:), intent(inout) :: data
        integer, intent(inout) :: nodata
        type(xs_annotation), dimension(:), pointer :: dvar
        logical, intent(inout) :: has_dvar

        integer :: newsize
        type(xs_annotation), dimension(:), pointer :: newvar

        newsize = size(dvar) + 1
        allocate (newvar(1:newsize))
        newvar(1:newsize - 1) = dvar
        deallocate (dvar)
        dvar => newvar

        call read_xml_type_xs_annotation(info, tag, endtag, attribs, noattribs, data, nodata, &
                                         dvar(newsize), has_dvar)
    end subroutine read_xml_type_xs_annotation_array

    subroutine read_xml_type_xs_annotation(info, starttag, endtag, attribs, noattribs, data, nodata, &
                                           dvar, has_dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(in) :: starttag
        logical, intent(inout) :: endtag
        character(len=*), dimension(:, :), intent(inout) :: attribs
        integer, intent(inout) :: noattribs
        character(len=*), dimension(:), intent(inout) :: data
        integer, intent(inout) :: nodata
        type(xs_annotation), intent(inout) :: dvar
        logical, intent(inout) :: has_dvar

        integer :: att_
        integer :: noatt_
        logical :: error
        logical :: endtag_org
        character(len=len(starttag)) :: tag
        logical :: has_documentation
        has_documentation = .false.
        allocate (dvar%documentation(0))
        call init_xml_type_xs_annotation(dvar)
        has_dvar = .true.
        error = .false.
        att_ = 0
        noatt_ = noattribs + 1
        endtag_org = endtag
        do
            if (nodata /= 0) then
                noattribs = 0
                tag = starttag
            elseif (att_ .lt. noatt_ .and. noatt_ .gt. 1) then
                att_ = att_ + 1
                if (att_ .le. noatt_ - 1) then
                    tag = attribs(1, att_)
                    data(1) = attribs(2, att_)
                    noattribs = 0
                    nodata = 1
                    endtag = .false.
                else
                    tag = starttag
                    noattribs = 0
                    nodata = 0
                    endtag = .true.
                    cycle
                end if
            else
                if (endtag_org) then
                    return
                else
                    call xml_get(info, tag, endtag, attribs, noattribs, data, nodata)
                    if (xml_error(info)) then
                        write (lurep_, *) 'Error reading input file!'
                        error = .true.
                        return
                    end if
                end if
            end if
            if (endtag .and. tag == starttag) then
                exit
            end if
            if (endtag .and. noattribs == 0) then
                if (xml_ok(info)) then
                    cycle
                else
                    exit
                end if
            end if
            select case (tag)
            case ('xs:documentation')
                call read_xml_line_1dim( &
                    info, tag, endtag, attribs, noattribs, data, nodata, &
                    dvar%documentation, has_documentation)
            case ('comment', '!--')
                ! Simply ignore
            case default
                if (strict_) then
                    error = .true.
                    call xml_report_errors(info, &
                                           'Unknown or wrongly placed tag: '//trim(tag))
                end if
            end select
            nodata = 0
            if (.not. xml_ok(info)) exit
        end do
        if (.not. has_documentation) then
            has_dvar = .false.
            call xml_report_errors(info, 'Missing data on documentation')
        end if
    end subroutine read_xml_type_xs_annotation
    subroutine init_xml_type_xs_annotation_array(dvar)
        type(xs_annotation), dimension(:), pointer :: dvar
        if (associated(dvar)) then
            deallocate (dvar)
        end if
        allocate (dvar(0))
    end subroutine init_xml_type_xs_annotation_array
    subroutine init_xml_type_xs_annotation(dvar)
        type(xs_annotation) :: dvar
    end subroutine init_xml_type_xs_annotation
    subroutine write_xml_type_xs_annotation_array( &
        info, tag, indent, dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(in) :: tag
        integer :: indent
        type(xs_annotation), dimension(:) :: dvar
        integer :: i
        do i = 1, size(dvar)
            call write_xml_type_xs_annotation(info, tag, indent, dvar(i))
        end do
    end subroutine write_xml_type_xs_annotation_array

    subroutine write_xml_type_xs_annotation( &
        info, tag, indent, dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(in) :: tag
        integer :: indent
        type(xs_annotation) :: dvar
        character(len=100) :: indentation
        indentation = ' '
        write (info%lun, '(4a)') indentation(1:min(indent, 100)), &
            '<', trim(tag), '>'
        call write_to_xml_line_1dim(info, 'xs:documentation', indent + 3, dvar%documentation)
        write (info%lun, '(4a)') indentation(1:min(indent, 100)), &
            '</'//trim(tag)//'>'
    end subroutine write_xml_type_xs_annotation

    subroutine read_xml_type_xs_component_array( &
        info, tag, endtag, attribs, noattribs, data, nodata, &
        dvar, has_dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(inout) :: tag
        logical, intent(inout) :: endtag
        character(len=*), dimension(:, :), intent(inout) :: attribs
        integer, intent(inout) :: noattribs
        character(len=*), dimension(:), intent(inout) :: data
        integer, intent(inout) :: nodata
        type(xs_component), dimension(:), pointer :: dvar
        logical, intent(inout) :: has_dvar

        integer :: newsize
        type(xs_component), dimension(:), pointer :: newvar

        newsize = size(dvar) + 1
        allocate (newvar(1:newsize))
        newvar(1:newsize - 1) = dvar
        deallocate (dvar)
        dvar => newvar

        call read_xml_type_xs_component(info, tag, endtag, attribs, noattribs, data, nodata, &
                                        dvar(newsize), has_dvar)
    end subroutine read_xml_type_xs_component_array

    subroutine read_xml_type_xs_component(info, starttag, endtag, attribs, noattribs, data, nodata, &
                                          dvar, has_dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(in) :: starttag
        logical, intent(inout) :: endtag
        character(len=*), dimension(:, :), intent(inout) :: attribs
        integer, intent(inout) :: noattribs
        character(len=*), dimension(:), intent(inout) :: data
        integer, intent(inout) :: nodata
        type(xs_component), intent(inout) :: dvar
        logical, intent(inout) :: has_dvar

        integer :: att_
        integer :: noatt_
        logical :: error
        logical :: endtag_org
        character(len=len(starttag)) :: tag
        logical :: has_ref
        logical :: has_minOccurs
        logical :: has_maxOccurs
        has_ref = .false.
        has_minOccurs = .false.
        has_maxOccurs = .false.
        call init_xml_type_xs_component(dvar)
        has_dvar = .true.
        error = .false.
        att_ = 0
        noatt_ = noattribs + 1
        endtag_org = endtag
        do
            if (nodata /= 0) then
                noattribs = 0
                tag = starttag
            elseif (att_ .lt. noatt_ .and. noatt_ .gt. 1) then
                att_ = att_ + 1
                if (att_ .le. noatt_ - 1) then
                    tag = attribs(1, att_)
                    data(1) = attribs(2, att_)
                    noattribs = 0
                    nodata = 1
                    endtag = .false.
                else
                    tag = starttag
                    noattribs = 0
                    nodata = 0
                    endtag = .true.
                    cycle
                end if
            else
                if (endtag_org) then
                    return
                else
                    call xml_get(info, tag, endtag, attribs, noattribs, data, nodata)
                    if (xml_error(info)) then
                        write (lurep_, *) 'Error reading input file!'
                        error = .true.
                        return
                    end if
                end if
            end if
            if (endtag .and. tag == starttag) then
                exit
            end if
            if (endtag .and. noattribs == 0) then
                if (xml_ok(info)) then
                    cycle
                else
                    exit
                end if
            end if
            select case (tag)
            case ('ref')
                call read_xml_word( &
                    info, tag, endtag, attribs, noattribs, data, nodata, &
                    dvar%ref, has_ref)
            case ('minOccurs')
                call read_xml_word( &
                    info, tag, endtag, attribs, noattribs, data, nodata, &
                    dvar%minOccurs, has_minOccurs)
            case ('maxOccurs')
                call read_xml_word( &
                    info, tag, endtag, attribs, noattribs, data, nodata, &
                    dvar%maxOccurs, has_maxOccurs)
            case ('comment', '!--')
                ! Simply ignore
            case default
                if (strict_) then
                    error = .true.
                    call xml_report_errors(info, &
                                           'Unknown or wrongly placed tag: '//trim(tag))
                end if
            end select
            nodata = 0
            if (.not. xml_ok(info)) exit
        end do
        if (.not. has_ref) then
            has_dvar = .false.
            call xml_report_errors(info, 'Missing data on ref')
        end if
    end subroutine read_xml_type_xs_component
    subroutine init_xml_type_xs_component_array(dvar)
        type(xs_component), dimension(:), pointer :: dvar
        if (associated(dvar)) then
            deallocate (dvar)
        end if
        allocate (dvar(0))
    end subroutine init_xml_type_xs_component_array
    subroutine init_xml_type_xs_component(dvar)
        type(xs_component) :: dvar
        dvar%minOccurs = '1'
        dvar%maxOccurs = '1'
    end subroutine init_xml_type_xs_component
    subroutine write_xml_type_xs_component_array( &
        info, tag, indent, dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(in) :: tag
        integer :: indent
        type(xs_component), dimension(:) :: dvar
        integer :: i
        do i = 1, size(dvar)
            call write_xml_type_xs_component(info, tag, indent, dvar(i))
        end do
    end subroutine write_xml_type_xs_component_array

    subroutine write_xml_type_xs_component( &
        info, tag, indent, dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(in) :: tag
        integer :: indent
        type(xs_component) :: dvar
        character(len=100) :: indentation
        indentation = ' '
        write (info%lun, '(4a)') indentation(1:min(indent, 100)), &
            '<', trim(tag), '>'
        call write_to_xml_word(info, 'ref', indent + 3, dvar%ref)
        call write_to_xml_word(info, 'minOccurs', indent + 3, dvar%minOccurs)
        call write_to_xml_word(info, 'maxOccurs', indent + 3, dvar%maxOccurs)
        write (info%lun, '(4a)') indentation(1:min(indent, 100)), &
            '</'//trim(tag)//'>'
    end subroutine write_xml_type_xs_component

    subroutine read_xml_type_xs_attribute_array( &
        info, tag, endtag, attribs, noattribs, data, nodata, &
        dvar, has_dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(inout) :: tag
        logical, intent(inout) :: endtag
        character(len=*), dimension(:, :), intent(inout) :: attribs
        integer, intent(inout) :: noattribs
        character(len=*), dimension(:), intent(inout) :: data
        integer, intent(inout) :: nodata
        type(xs_attribute), dimension(:), pointer :: dvar
        logical, intent(inout) :: has_dvar

        integer :: newsize
        type(xs_attribute), dimension(:), pointer :: newvar

        newsize = size(dvar) + 1
        allocate (newvar(1:newsize))
        newvar(1:newsize - 1) = dvar
        deallocate (dvar)
        dvar => newvar

        call read_xml_type_xs_attribute(info, tag, endtag, attribs, noattribs, data, nodata, &
                                        dvar(newsize), has_dvar)
    end subroutine read_xml_type_xs_attribute_array

    subroutine read_xml_type_xs_attribute(info, starttag, endtag, attribs, noattribs, data, nodata, &
                                          dvar, has_dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(in) :: starttag
        logical, intent(inout) :: endtag
        character(len=*), dimension(:, :), intent(inout) :: attribs
        integer, intent(inout) :: noattribs
        character(len=*), dimension(:), intent(inout) :: data
        integer, intent(inout) :: nodata
        type(xs_attribute), intent(inout) :: dvar
        logical, intent(inout) :: has_dvar

        integer :: att_
        integer :: noatt_
        logical :: error
        logical :: endtag_org
        character(len=len(starttag)) :: tag
        logical :: has_name
        logical :: has_type
        logical :: has_use
        has_name = .false.
        has_type = .false.
        has_use = .false.
        call init_xml_type_xs_attribute(dvar)
        has_dvar = .true.
        error = .false.
        att_ = 0
        noatt_ = noattribs + 1
        endtag_org = endtag
        do
            if (nodata /= 0) then
                noattribs = 0
                tag = starttag
            elseif (att_ .lt. noatt_ .and. noatt_ .gt. 1) then
                att_ = att_ + 1
                if (att_ .le. noatt_ - 1) then
                    tag = attribs(1, att_)
                    data(1) = attribs(2, att_)
                    noattribs = 0
                    nodata = 1
                    endtag = .false.
                else
                    tag = starttag
                    noattribs = 0
                    nodata = 0
                    endtag = .true.
                    cycle
                end if
            else
                if (endtag_org) then
                    return
                else
                    call xml_get(info, tag, endtag, attribs, noattribs, data, nodata)
                    if (xml_error(info)) then
                        write (lurep_, *) 'Error reading input file!'
                        error = .true.
                        return
                    end if
                end if
            end if
            if (endtag .and. tag == starttag) then
                exit
            end if
            if (endtag .and. noattribs == 0) then
                if (xml_ok(info)) then
                    cycle
                else
                    exit
                end if
            end if
            select case (tag)
            case ('name')
                call read_xml_word( &
                    info, tag, endtag, attribs, noattribs, data, nodata, &
                    dvar%name, has_name)
            case ('type')
                call read_xml_word( &
                    info, tag, endtag, attribs, noattribs, data, nodata, &
                    dvar%type, has_type)
            case ('use')
                call read_xml_word( &
                    info, tag, endtag, attribs, noattribs, data, nodata, &
                    dvar%use, has_use)
            case ('comment', '!--')
                ! Simply ignore
            case default
                if (strict_) then
                    error = .true.
                    call xml_report_errors(info, &
                                           'Unknown or wrongly placed tag: '//trim(tag))
                end if
            end select
            nodata = 0
            if (.not. xml_ok(info)) exit
        end do
        if (.not. has_name) then
            has_dvar = .false.
            call xml_report_errors(info, 'Missing data on name')
        end if
        if (.not. has_type) then
            has_dvar = .false.
            call xml_report_errors(info, 'Missing data on type')
        end if
        if (.not. has_use) then
            has_dvar = .false.
            call xml_report_errors(info, 'Missing data on use')
        end if
    end subroutine read_xml_type_xs_attribute
    subroutine init_xml_type_xs_attribute_array(dvar)
        type(xs_attribute), dimension(:), pointer :: dvar
        if (associated(dvar)) then
            deallocate (dvar)
        end if
        allocate (dvar(0))
    end subroutine init_xml_type_xs_attribute_array
    subroutine init_xml_type_xs_attribute(dvar)
        type(xs_attribute) :: dvar
    end subroutine init_xml_type_xs_attribute
    subroutine write_xml_type_xs_attribute_array( &
        info, tag, indent, dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(in) :: tag
        integer :: indent
        type(xs_attribute), dimension(:) :: dvar
        integer :: i
        do i = 1, size(dvar)
            call write_xml_type_xs_attribute(info, tag, indent, dvar(i))
        end do
    end subroutine write_xml_type_xs_attribute_array

    subroutine write_xml_type_xs_attribute( &
        info, tag, indent, dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(in) :: tag
        integer :: indent
        type(xs_attribute) :: dvar
        character(len=100) :: indentation
        indentation = ' '
        write (info%lun, '(4a)') indentation(1:min(indent, 100)), &
            '<', trim(tag), '>'
        call write_to_xml_word(info, 'name', indent + 3, dvar%name)
        call write_to_xml_word(info, 'type', indent + 3, dvar%type)
        call write_to_xml_word(info, 'use', indent + 3, dvar%use)
        write (info%lun, '(4a)') indentation(1:min(indent, 100)), &
            '</'//trim(tag)//'>'
    end subroutine write_xml_type_xs_attribute

    subroutine read_xml_type_xs_restriction_array( &
        info, tag, endtag, attribs, noattribs, data, nodata, &
        dvar, has_dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(inout) :: tag
        logical, intent(inout) :: endtag
        character(len=*), dimension(:, :), intent(inout) :: attribs
        integer, intent(inout) :: noattribs
        character(len=*), dimension(:), intent(inout) :: data
        integer, intent(inout) :: nodata
        type(xs_restriction), dimension(:), pointer :: dvar
        logical, intent(inout) :: has_dvar

        integer :: newsize
        type(xs_restriction), dimension(:), pointer :: newvar

        newsize = size(dvar) + 1
        allocate (newvar(1:newsize))
        newvar(1:newsize - 1) = dvar
        deallocate (dvar)
        dvar => newvar

        call read_xml_type_xs_restriction(info, tag, endtag, attribs, noattribs, data, nodata, &
                                          dvar(newsize), has_dvar)
    end subroutine read_xml_type_xs_restriction_array

    subroutine read_xml_type_xs_restriction(info, starttag, endtag, attribs, noattribs, data, nodata, &
                                            dvar, has_dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(in) :: starttag
        logical, intent(inout) :: endtag
        character(len=*), dimension(:, :), intent(inout) :: attribs
        integer, intent(inout) :: noattribs
        character(len=*), dimension(:), intent(inout) :: data
        integer, intent(inout) :: nodata
        type(xs_restriction), intent(inout) :: dvar
        logical, intent(inout) :: has_dvar

        integer :: att_
        integer :: noatt_
        logical :: error
        logical :: endtag_org
        character(len=len(starttag)) :: tag
        logical :: has_base
        logical :: has_enumeration
        logical :: has_minInclusive
        logical :: has_maxInclusive
        logical :: has_pattern
        has_base = .false.
        has_enumeration = .false.
        allocate (dvar%enumeration(0))
        has_minInclusive = .false.
        has_maxInclusive = .false.
        has_pattern = .false.
        call init_xml_type_xs_restriction(dvar)
        has_dvar = .true.
        error = .false.
        att_ = 0
        noatt_ = noattribs + 1
        endtag_org = endtag
        do
            if (nodata /= 0) then
                noattribs = 0
                tag = starttag
            elseif (att_ .lt. noatt_ .and. noatt_ .gt. 1) then
                att_ = att_ + 1
                if (att_ .le. noatt_ - 1) then
                    tag = attribs(1, att_)
                    data(1) = attribs(2, att_)
                    noattribs = 0
                    nodata = 1
                    endtag = .false.
                else
                    tag = starttag
                    noattribs = 0
                    nodata = 0
                    endtag = .true.
                    cycle
                end if
            else
                if (endtag_org) then
                    return
                else
                    call xml_get(info, tag, endtag, attribs, noattribs, data, nodata)
                    if (xml_error(info)) then
                        write (lurep_, *) 'Error reading input file!'
                        error = .true.
                        return
                    end if
                end if
            end if
            if (endtag .and. tag == starttag) then
                exit
            end if
            if (endtag .and. noattribs == 0) then
                if (xml_ok(info)) then
                    cycle
                else
                    exit
                end if
            end if
            select case (tag)
            case ('base')
                call read_xml_word( &
                    info, tag, endtag, attribs, noattribs, data, nodata, &
                    dvar%base, has_base)
            case ('enumeration')
                call read_xml_word_1dim( &
                    info, tag, endtag, attribs, noattribs, data, nodata, &
                    dvar%enumeration, has_enumeration)
            case ('minInclusive')
                call read_xml_integer( &
                    info, tag, endtag, attribs, noattribs, data, nodata, &
                    dvar%minInclusive, has_minInclusive)
            case ('maxInclusive')
                call read_xml_integer( &
                    info, tag, endtag, attribs, noattribs, data, nodata, &
                    dvar%maxInclusive, has_maxInclusive)
            case ('pattern')
                call read_xml_word( &
                    info, tag, endtag, attribs, noattribs, data, nodata, &
                    dvar%pattern, has_pattern)
            case ('comment', '!--')
                ! Simply ignore
            case default
                if (strict_) then
                    error = .true.
                    call xml_report_errors(info, &
                                           'Unknown or wrongly placed tag: '//trim(tag))
                end if
            end select
            nodata = 0
            if (.not. xml_ok(info)) exit
        end do
    end subroutine read_xml_type_xs_restriction
    subroutine init_xml_type_xs_restriction_array(dvar)
        type(xs_restriction), dimension(:), pointer :: dvar
        if (associated(dvar)) then
            deallocate (dvar)
        end if
        allocate (dvar(0))
    end subroutine init_xml_type_xs_restriction_array
    subroutine init_xml_type_xs_restriction(dvar)
        type(xs_restriction) :: dvar
        dvar%base = 'integer'
        dvar%enumeration = '?'
        dvar%minInclusive = 0
        dvar%maxInclusive = 0
        dvar%pattern = '.*'
    end subroutine init_xml_type_xs_restriction
    subroutine write_xml_type_xs_restriction_array( &
        info, tag, indent, dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(in) :: tag
        integer :: indent
        type(xs_restriction), dimension(:) :: dvar
        integer :: i
        do i = 1, size(dvar)
            call write_xml_type_xs_restriction(info, tag, indent, dvar(i))
        end do
    end subroutine write_xml_type_xs_restriction_array

    subroutine write_xml_type_xs_restriction( &
        info, tag, indent, dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(in) :: tag
        integer :: indent
        type(xs_restriction) :: dvar
        character(len=100) :: indentation
        indentation = ' '
        write (info%lun, '(4a)') indentation(1:min(indent, 100)), &
            '<', trim(tag), '>'
        call write_to_xml_word(info, 'base', indent + 3, dvar%base)
        call write_to_xml_word_1dim(info, 'enumeration', indent + 3, dvar%enumeration)
        call write_to_xml_integer(info, 'minInclusive', indent + 3, dvar%minInclusive)
        call write_to_xml_integer(info, 'maxInclusive', indent + 3, dvar%maxInclusive)
        call write_to_xml_word(info, 'pattern', indent + 3, dvar%pattern)
        write (info%lun, '(4a)') indentation(1:min(indent, 100)), &
            '</'//trim(tag)//'>'
    end subroutine write_xml_type_xs_restriction

    subroutine read_xml_type_xs_union_array( &
        info, tag, endtag, attribs, noattribs, data, nodata, &
        dvar, has_dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(inout) :: tag
        logical, intent(inout) :: endtag
        character(len=*), dimension(:, :), intent(inout) :: attribs
        integer, intent(inout) :: noattribs
        character(len=*), dimension(:), intent(inout) :: data
        integer, intent(inout) :: nodata
        type(xs_union), dimension(:), pointer :: dvar
        logical, intent(inout) :: has_dvar

        integer :: newsize
        type(xs_union), dimension(:), pointer :: newvar

        newsize = size(dvar) + 1
        allocate (newvar(1:newsize))
        newvar(1:newsize - 1) = dvar
        deallocate (dvar)
        dvar => newvar

        call read_xml_type_xs_union(info, tag, endtag, attribs, noattribs, data, nodata, &
                                    dvar(newsize), has_dvar)
    end subroutine read_xml_type_xs_union_array

    subroutine read_xml_type_xs_union(info, starttag, endtag, attribs, noattribs, data, nodata, &
                                      dvar, has_dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(in) :: starttag
        logical, intent(inout) :: endtag
        character(len=*), dimension(:, :), intent(inout) :: attribs
        integer, intent(inout) :: noattribs
        character(len=*), dimension(:), intent(inout) :: data
        integer, intent(inout) :: nodata
        type(xs_union), intent(inout) :: dvar
        logical, intent(inout) :: has_dvar

        integer :: att_
        integer :: noatt_
        logical :: error
        logical :: endtag_org
        character(len=len(starttag)) :: tag
        logical :: has_memberTypes
        has_memberTypes = .false.
        call init_xml_type_xs_union(dvar)
        has_dvar = .true.
        error = .false.
        att_ = 0
        noatt_ = noattribs + 1
        endtag_org = endtag
        do
            if (nodata /= 0) then
                noattribs = 0
                tag = starttag
            elseif (att_ .lt. noatt_ .and. noatt_ .gt. 1) then
                att_ = att_ + 1
                if (att_ .le. noatt_ - 1) then
                    tag = attribs(1, att_)
                    data(1) = attribs(2, att_)
                    noattribs = 0
                    nodata = 1
                    endtag = .false.
                else
                    tag = starttag
                    noattribs = 0
                    nodata = 0
                    endtag = .true.
                    cycle
                end if
            else
                if (endtag_org) then
                    return
                else
                    call xml_get(info, tag, endtag, attribs, noattribs, data, nodata)
                    if (xml_error(info)) then
                        write (lurep_, *) 'Error reading input file!'
                        error = .true.
                        return
                    end if
                end if
            end if
            if (endtag .and. tag == starttag) then
                exit
            end if
            if (endtag .and. noattribs == 0) then
                if (xml_ok(info)) then
                    cycle
                else
                    exit
                end if
            end if
            select case (tag)
            case ('memberTypes')
                call read_xml_word( &
                    info, tag, endtag, attribs, noattribs, data, nodata, &
                    dvar%memberTypes, has_memberTypes)
            case ('comment', '!--')
                ! Simply ignore
            case default
                if (strict_) then
                    error = .true.
                    call xml_report_errors(info, &
                                           'Unknown or wrongly placed tag: '//trim(tag))
                end if
            end select
            nodata = 0
            if (.not. xml_ok(info)) exit
        end do
    end subroutine read_xml_type_xs_union
    subroutine init_xml_type_xs_union_array(dvar)
        type(xs_union), dimension(:), pointer :: dvar
        if (associated(dvar)) then
            deallocate (dvar)
        end if
        allocate (dvar(0))
    end subroutine init_xml_type_xs_union_array
    subroutine init_xml_type_xs_union(dvar)
        type(xs_union) :: dvar
        dvar%memberTypes = '?'
    end subroutine init_xml_type_xs_union
    subroutine write_xml_type_xs_union_array( &
        info, tag, indent, dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(in) :: tag
        integer :: indent
        type(xs_union), dimension(:) :: dvar
        integer :: i
        do i = 1, size(dvar)
            call write_xml_type_xs_union(info, tag, indent, dvar(i))
        end do
    end subroutine write_xml_type_xs_union_array

    subroutine write_xml_type_xs_union( &
        info, tag, indent, dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(in) :: tag
        integer :: indent
        type(xs_union) :: dvar
        character(len=100) :: indentation
        indentation = ' '
        write (info%lun, '(4a)') indentation(1:min(indent, 100)), &
            '<', trim(tag), '>'
        call write_to_xml_word(info, 'memberTypes', indent + 3, dvar%memberTypes)
        write (info%lun, '(4a)') indentation(1:min(indent, 100)), &
            '</'//trim(tag)//'>'
    end subroutine write_xml_type_xs_union

    subroutine read_xml_type_xs_extension_array( &
        info, tag, endtag, attribs, noattribs, data, nodata, &
        dvar, has_dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(inout) :: tag
        logical, intent(inout) :: endtag
        character(len=*), dimension(:, :), intent(inout) :: attribs
        integer, intent(inout) :: noattribs
        character(len=*), dimension(:), intent(inout) :: data
        integer, intent(inout) :: nodata
        type(xs_extension), dimension(:), pointer :: dvar
        logical, intent(inout) :: has_dvar

        integer :: newsize
        type(xs_extension), dimension(:), pointer :: newvar

        newsize = size(dvar) + 1
        allocate (newvar(1:newsize))
        newvar(1:newsize - 1) = dvar
        deallocate (dvar)
        dvar => newvar

        call read_xml_type_xs_extension(info, tag, endtag, attribs, noattribs, data, nodata, &
                                        dvar(newsize), has_dvar)
    end subroutine read_xml_type_xs_extension_array

    subroutine read_xml_type_xs_extension(info, starttag, endtag, attribs, noattribs, data, nodata, &
                                          dvar, has_dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(in) :: starttag
        logical, intent(inout) :: endtag
        character(len=*), dimension(:, :), intent(inout) :: attribs
        integer, intent(inout) :: noattribs
        character(len=*), dimension(:), intent(inout) :: data
        integer, intent(inout) :: nodata
        type(xs_extension), intent(inout) :: dvar
        logical, intent(inout) :: has_dvar

        integer :: att_
        integer :: noatt_
        logical :: error
        logical :: endtag_org
        character(len=len(starttag)) :: tag
        logical :: has_attribute
        has_attribute = .false.
        allocate (dvar%attribute(0))
        call init_xml_type_xs_extension(dvar)
        has_dvar = .true.
        error = .false.
        att_ = 0
        noatt_ = noattribs + 1
        endtag_org = endtag
        do
            if (nodata /= 0) then
                noattribs = 0
                tag = starttag
            elseif (att_ .lt. noatt_ .and. noatt_ .gt. 1) then
                att_ = att_ + 1
                if (att_ .le. noatt_ - 1) then
                    tag = attribs(1, att_)
                    data(1) = attribs(2, att_)
                    noattribs = 0
                    nodata = 1
                    endtag = .false.
                else
                    tag = starttag
                    noattribs = 0
                    nodata = 0
                    endtag = .true.
                    cycle
                end if
            else
                if (endtag_org) then
                    return
                else
                    call xml_get(info, tag, endtag, attribs, noattribs, data, nodata)
                    if (xml_error(info)) then
                        write (lurep_, *) 'Error reading input file!'
                        error = .true.
                        return
                    end if
                end if
            end if
            if (endtag .and. tag == starttag) then
                exit
            end if
            if (endtag .and. noattribs == 0) then
                if (xml_ok(info)) then
                    cycle
                else
                    exit
                end if
            end if
            select case (tag)
            case ('xs:attribute')
                call read_xml_type_xs_attribute_array( &
                    info, tag, endtag, attribs, noattribs, data, nodata, &
                    dvar%attribute, has_attribute)
            case ('comment', '!--')
                ! Simply ignore
            case default
                if (strict_) then
                    error = .true.
                    call xml_report_errors(info, &
                                           'Unknown or wrongly placed tag: '//trim(tag))
                end if
            end select
            nodata = 0
            if (.not. xml_ok(info)) exit
        end do
    end subroutine read_xml_type_xs_extension
    subroutine init_xml_type_xs_extension_array(dvar)
        type(xs_extension), dimension(:), pointer :: dvar
        if (associated(dvar)) then
            deallocate (dvar)
        end if
        allocate (dvar(0))
    end subroutine init_xml_type_xs_extension_array
    subroutine init_xml_type_xs_extension(dvar)
        type(xs_extension) :: dvar
        dvar%attribute = xs_attribute('?', '?', '?')
    end subroutine init_xml_type_xs_extension
    subroutine write_xml_type_xs_extension_array( &
        info, tag, indent, dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(in) :: tag
        integer :: indent
        type(xs_extension), dimension(:) :: dvar
        integer :: i
        do i = 1, size(dvar)
            call write_xml_type_xs_extension(info, tag, indent, dvar(i))
        end do
    end subroutine write_xml_type_xs_extension_array

    subroutine write_xml_type_xs_extension( &
        info, tag, indent, dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(in) :: tag
        integer :: indent
        type(xs_extension) :: dvar
        character(len=100) :: indentation
        indentation = ' '
        write (info%lun, '(4a)') indentation(1:min(indent, 100)), &
            '<', trim(tag), '>'
        call write_xml_type_xs_attribute_array(info, 'xs:attribute', indent + 3, dvar%attribute)
        write (info%lun, '(4a)') indentation(1:min(indent, 100)), &
            '</'//trim(tag)//'>'
    end subroutine write_xml_type_xs_extension

    subroutine read_xml_type_xs_simpleContent_array( &
        info, tag, endtag, attribs, noattribs, data, nodata, &
        dvar, has_dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(inout) :: tag
        logical, intent(inout) :: endtag
        character(len=*), dimension(:, :), intent(inout) :: attribs
        integer, intent(inout) :: noattribs
        character(len=*), dimension(:), intent(inout) :: data
        integer, intent(inout) :: nodata
        type(xs_simpleContent), dimension(:), pointer :: dvar
        logical, intent(inout) :: has_dvar

        integer :: newsize
        type(xs_simpleContent), dimension(:), pointer :: newvar

        newsize = size(dvar) + 1
        allocate (newvar(1:newsize))
        newvar(1:newsize - 1) = dvar
        deallocate (dvar)
        dvar => newvar

        call read_xml_type_xs_simpleContent(info, tag, endtag, attribs, noattribs, data, nodata, &
                                            dvar(newsize), has_dvar)
    end subroutine read_xml_type_xs_simpleContent_array

    subroutine read_xml_type_xs_simpleContent(info, starttag, endtag, attribs, noattribs, data, nodata, &
                                              dvar, has_dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(in) :: starttag
        logical, intent(inout) :: endtag
        character(len=*), dimension(:, :), intent(inout) :: attribs
        integer, intent(inout) :: noattribs
        character(len=*), dimension(:), intent(inout) :: data
        integer, intent(inout) :: nodata
        type(xs_simpleContent), intent(inout) :: dvar
        logical, intent(inout) :: has_dvar

        integer :: att_
        integer :: noatt_
        logical :: error
        logical :: endtag_org
        character(len=len(starttag)) :: tag
        logical :: has_extension
        has_extension = .false.
        call init_xml_type_xs_simpleContent(dvar)
        has_dvar = .true.
        error = .false.
        att_ = 0
        noatt_ = noattribs + 1
        endtag_org = endtag
        do
            if (nodata /= 0) then
                noattribs = 0
                tag = starttag
            elseif (att_ .lt. noatt_ .and. noatt_ .gt. 1) then
                att_ = att_ + 1
                if (att_ .le. noatt_ - 1) then
                    tag = attribs(1, att_)
                    data(1) = attribs(2, att_)
                    noattribs = 0
                    nodata = 1
                    endtag = .false.
                else
                    tag = starttag
                    noattribs = 0
                    nodata = 0
                    endtag = .true.
                    cycle
                end if
            else
                if (endtag_org) then
                    return
                else
                    call xml_get(info, tag, endtag, attribs, noattribs, data, nodata)
                    if (xml_error(info)) then
                        write (lurep_, *) 'Error reading input file!'
                        error = .true.
                        return
                    end if
                end if
            end if
            if (endtag .and. tag == starttag) then
                exit
            end if
            if (endtag .and. noattribs == 0) then
                if (xml_ok(info)) then
                    cycle
                else
                    exit
                end if
            end if
            select case (tag)
            case ('xs:extension')
                call read_xml_type_xs_extension( &
                    info, tag, endtag, attribs, noattribs, data, nodata, &
                    dvar%extension, has_extension)
            case ('comment', '!--')
                ! Simply ignore
            case default
                if (strict_) then
                    error = .true.
                    call xml_report_errors(info, &
                                           'Unknown or wrongly placed tag: '//trim(tag))
                end if
            end select
            nodata = 0
            if (.not. xml_ok(info)) exit
        end do
        if (.not. has_extension) then
            has_dvar = .false.
            call xml_report_errors(info, 'Missing data on extension')
        end if
    end subroutine read_xml_type_xs_simpleContent
    subroutine init_xml_type_xs_simpleContent_array(dvar)
        type(xs_simpleContent), dimension(:), pointer :: dvar
        if (associated(dvar)) then
            deallocate (dvar)
        end if
        allocate (dvar(0))
    end subroutine init_xml_type_xs_simpleContent_array
    subroutine init_xml_type_xs_simpleContent(dvar)
        type(xs_simpleContent) :: dvar
    end subroutine init_xml_type_xs_simpleContent
    subroutine write_xml_type_xs_simpleContent_array( &
        info, tag, indent, dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(in) :: tag
        integer :: indent
        type(xs_simpleContent), dimension(:) :: dvar
        integer :: i
        do i = 1, size(dvar)
            call write_xml_type_xs_simpleContent(info, tag, indent, dvar(i))
        end do
    end subroutine write_xml_type_xs_simpleContent_array

    subroutine write_xml_type_xs_simpleContent( &
        info, tag, indent, dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(in) :: tag
        integer :: indent
        type(xs_simpleContent) :: dvar
        character(len=100) :: indentation
        indentation = ' '
        write (info%lun, '(4a)') indentation(1:min(indent, 100)), &
            '<', trim(tag), '>'
        call write_xml_type_xs_extension(info, 'xs:extension', indent + 3, dvar%extension)
        write (info%lun, '(4a)') indentation(1:min(indent, 100)), &
            '</'//trim(tag)//'>'
    end subroutine write_xml_type_xs_simpleContent

    subroutine read_xml_type_xs_sequence_array( &
        info, tag, endtag, attribs, noattribs, data, nodata, &
        dvar, has_dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(inout) :: tag
        logical, intent(inout) :: endtag
        character(len=*), dimension(:, :), intent(inout) :: attribs
        integer, intent(inout) :: noattribs
        character(len=*), dimension(:), intent(inout) :: data
        integer, intent(inout) :: nodata
        type(xs_sequence), dimension(:), pointer :: dvar
        logical, intent(inout) :: has_dvar

        integer :: newsize
        type(xs_sequence), dimension(:), pointer :: newvar

        newsize = size(dvar) + 1
        allocate (newvar(1:newsize))
        newvar(1:newsize - 1) = dvar
        deallocate (dvar)
        dvar => newvar

        call read_xml_type_xs_sequence(info, tag, endtag, attribs, noattribs, data, nodata, &
                                       dvar(newsize), has_dvar)
    end subroutine read_xml_type_xs_sequence_array

    subroutine read_xml_type_xs_sequence(info, starttag, endtag, attribs, noattribs, data, nodata, &
                                         dvar, has_dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(in) :: starttag
        logical, intent(inout) :: endtag
        character(len=*), dimension(:, :), intent(inout) :: attribs
        integer, intent(inout) :: noattribs
        character(len=*), dimension(:), intent(inout) :: data
        integer, intent(inout) :: nodata
        type(xs_sequence), intent(inout) :: dvar
        logical, intent(inout) :: has_dvar

        integer :: att_
        integer :: noatt_
        logical :: error
        logical :: endtag_org
        character(len=len(starttag)) :: tag
        logical :: has_component
        has_component = .false.
        allocate (dvar%component(0))
        call init_xml_type_xs_sequence(dvar)
        has_dvar = .true.
        error = .false.
        att_ = 0
        noatt_ = noattribs + 1
        endtag_org = endtag
        do
            if (nodata /= 0) then
                noattribs = 0
                tag = starttag
            elseif (att_ .lt. noatt_ .and. noatt_ .gt. 1) then
                att_ = att_ + 1
                if (att_ .le. noatt_ - 1) then
                    tag = attribs(1, att_)
                    data(1) = attribs(2, att_)
                    noattribs = 0
                    nodata = 1
                    endtag = .false.
                else
                    tag = starttag
                    noattribs = 0
                    nodata = 0
                    endtag = .true.
                    cycle
                end if
            else
                if (endtag_org) then
                    return
                else
                    call xml_get(info, tag, endtag, attribs, noattribs, data, nodata)
                    if (xml_error(info)) then
                        write (lurep_, *) 'Error reading input file!'
                        error = .true.
                        return
                    end if
                end if
            end if
            if (endtag .and. tag == starttag) then
                exit
            end if
            if (endtag .and. noattribs == 0) then
                if (xml_ok(info)) then
                    cycle
                else
                    exit
                end if
            end if
            select case (tag)
            case ('xs:element')
                call read_xml_type_xs_component_array( &
                    info, tag, endtag, attribs, noattribs, data, nodata, &
                    dvar%component, has_component)
            case ('comment', '!--')
                ! Simply ignore
            case default
                if (strict_) then
                    error = .true.
                    call xml_report_errors(info, &
                                           'Unknown or wrongly placed tag: '//trim(tag))
                end if
            end select
            nodata = 0
            if (.not. xml_ok(info)) exit
        end do
        if (.not. has_component) then
            has_dvar = .false.
            call xml_report_errors(info, 'Missing data on component')
        end if
    end subroutine read_xml_type_xs_sequence
    subroutine init_xml_type_xs_sequence_array(dvar)
        type(xs_sequence), dimension(:), pointer :: dvar
        if (associated(dvar)) then
            deallocate (dvar)
        end if
        allocate (dvar(0))
    end subroutine init_xml_type_xs_sequence_array
    subroutine init_xml_type_xs_sequence(dvar)
        type(xs_sequence) :: dvar
    end subroutine init_xml_type_xs_sequence
    subroutine write_xml_type_xs_sequence_array( &
        info, tag, indent, dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(in) :: tag
        integer :: indent
        type(xs_sequence), dimension(:) :: dvar
        integer :: i
        do i = 1, size(dvar)
            call write_xml_type_xs_sequence(info, tag, indent, dvar(i))
        end do
    end subroutine write_xml_type_xs_sequence_array

    subroutine write_xml_type_xs_sequence( &
        info, tag, indent, dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(in) :: tag
        integer :: indent
        type(xs_sequence) :: dvar
        character(len=100) :: indentation
        indentation = ' '
        write (info%lun, '(4a)') indentation(1:min(indent, 100)), &
            '<', trim(tag), '>'
        call write_xml_type_xs_component_array(info, 'xs:element', indent + 3, dvar%component)
        write (info%lun, '(4a)') indentation(1:min(indent, 100)), &
            '</'//trim(tag)//'>'
    end subroutine write_xml_type_xs_sequence

    subroutine read_xml_type_xs_all_array( &
        info, tag, endtag, attribs, noattribs, data, nodata, &
        dvar, has_dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(inout) :: tag
        logical, intent(inout) :: endtag
        character(len=*), dimension(:, :), intent(inout) :: attribs
        integer, intent(inout) :: noattribs
        character(len=*), dimension(:), intent(inout) :: data
        integer, intent(inout) :: nodata
        type(xs_all), dimension(:), pointer :: dvar
        logical, intent(inout) :: has_dvar

        integer :: newsize
        type(xs_all), dimension(:), pointer :: newvar

        newsize = size(dvar) + 1
        allocate (newvar(1:newsize))
        newvar(1:newsize - 1) = dvar
        deallocate (dvar)
        dvar => newvar

        call read_xml_type_xs_all(info, tag, endtag, attribs, noattribs, data, nodata, &
                                  dvar(newsize), has_dvar)
    end subroutine read_xml_type_xs_all_array

    subroutine read_xml_type_xs_all(info, starttag, endtag, attribs, noattribs, data, nodata, &
                                    dvar, has_dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(in) :: starttag
        logical, intent(inout) :: endtag
        character(len=*), dimension(:, :), intent(inout) :: attribs
        integer, intent(inout) :: noattribs
        character(len=*), dimension(:), intent(inout) :: data
        integer, intent(inout) :: nodata
        type(xs_all), intent(inout) :: dvar
        logical, intent(inout) :: has_dvar

        integer :: att_
        integer :: noatt_
        logical :: error
        logical :: endtag_org
        character(len=len(starttag)) :: tag
        logical :: has_component
        has_component = .false.
        allocate (dvar%component(0))
        call init_xml_type_xs_all(dvar)
        has_dvar = .true.
        error = .false.
        att_ = 0
        noatt_ = noattribs + 1
        endtag_org = endtag
        do
            if (nodata /= 0) then
                noattribs = 0
                tag = starttag
            elseif (att_ .lt. noatt_ .and. noatt_ .gt. 1) then
                att_ = att_ + 1
                if (att_ .le. noatt_ - 1) then
                    tag = attribs(1, att_)
                    data(1) = attribs(2, att_)
                    noattribs = 0
                    nodata = 1
                    endtag = .false.
                else
                    tag = starttag
                    noattribs = 0
                    nodata = 0
                    endtag = .true.
                    cycle
                end if
            else
                if (endtag_org) then
                    return
                else
                    call xml_get(info, tag, endtag, attribs, noattribs, data, nodata)
                    if (xml_error(info)) then
                        write (lurep_, *) 'Error reading input file!'
                        error = .true.
                        return
                    end if
                end if
            end if
            if (endtag .and. tag == starttag) then
                exit
            end if
            if (endtag .and. noattribs == 0) then
                if (xml_ok(info)) then
                    cycle
                else
                    exit
                end if
            end if
            select case (tag)
            case ('xs:element')
                call read_xml_type_xs_component_array( &
                    info, tag, endtag, attribs, noattribs, data, nodata, &
                    dvar%component, has_component)
            case ('comment', '!--')
                ! Simply ignore
            case default
                if (strict_) then
                    error = .true.
                    call xml_report_errors(info, &
                                           'Unknown or wrongly placed tag: '//trim(tag))
                end if
            end select
            nodata = 0
            if (.not. xml_ok(info)) exit
        end do
        if (.not. has_component) then
            has_dvar = .false.
            call xml_report_errors(info, 'Missing data on component')
        end if
    end subroutine read_xml_type_xs_all
    subroutine init_xml_type_xs_all_array(dvar)
        type(xs_all), dimension(:), pointer :: dvar
        if (associated(dvar)) then
            deallocate (dvar)
        end if
        allocate (dvar(0))
    end subroutine init_xml_type_xs_all_array
    subroutine init_xml_type_xs_all(dvar)
        type(xs_all) :: dvar
    end subroutine init_xml_type_xs_all
    subroutine write_xml_type_xs_all_array( &
        info, tag, indent, dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(in) :: tag
        integer :: indent
        type(xs_all), dimension(:) :: dvar
        integer :: i
        do i = 1, size(dvar)
            call write_xml_type_xs_all(info, tag, indent, dvar(i))
        end do
    end subroutine write_xml_type_xs_all_array

    subroutine write_xml_type_xs_all( &
        info, tag, indent, dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(in) :: tag
        integer :: indent
        type(xs_all) :: dvar
        character(len=100) :: indentation
        indentation = ' '
        write (info%lun, '(4a)') indentation(1:min(indent, 100)), &
            '<', trim(tag), '>'
        call write_xml_type_xs_component_array(info, 'xs:element', indent + 3, dvar%component)
        write (info%lun, '(4a)') indentation(1:min(indent, 100)), &
            '</'//trim(tag)//'>'
    end subroutine write_xml_type_xs_all

    subroutine read_xml_type_xs_choice_array( &
        info, tag, endtag, attribs, noattribs, data, nodata, &
        dvar, has_dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(inout) :: tag
        logical, intent(inout) :: endtag
        character(len=*), dimension(:, :), intent(inout) :: attribs
        integer, intent(inout) :: noattribs
        character(len=*), dimension(:), intent(inout) :: data
        integer, intent(inout) :: nodata
        type(xs_choice), dimension(:), pointer :: dvar
        logical, intent(inout) :: has_dvar

        integer :: newsize
        type(xs_choice), dimension(:), pointer :: newvar

        newsize = size(dvar) + 1
        allocate (newvar(1:newsize))
        newvar(1:newsize - 1) = dvar
        deallocate (dvar)
        dvar => newvar

        call read_xml_type_xs_choice(info, tag, endtag, attribs, noattribs, data, nodata, &
                                     dvar(newsize), has_dvar)
    end subroutine read_xml_type_xs_choice_array

    subroutine read_xml_type_xs_choice(info, starttag, endtag, attribs, noattribs, data, nodata, &
                                       dvar, has_dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(in) :: starttag
        logical, intent(inout) :: endtag
        character(len=*), dimension(:, :), intent(inout) :: attribs
        integer, intent(inout) :: noattribs
        character(len=*), dimension(:), intent(inout) :: data
        integer, intent(inout) :: nodata
        type(xs_choice), intent(inout) :: dvar
        logical, intent(inout) :: has_dvar

        integer :: att_
        integer :: noatt_
        logical :: error
        logical :: endtag_org
        character(len=len(starttag)) :: tag
        logical :: has_component
        has_component = .false.
        allocate (dvar%component(0))
        call init_xml_type_xs_choice(dvar)
        has_dvar = .true.
        error = .false.
        att_ = 0
        noatt_ = noattribs + 1
        endtag_org = endtag
        do
            if (nodata /= 0) then
                noattribs = 0
                tag = starttag
            elseif (att_ .lt. noatt_ .and. noatt_ .gt. 1) then
                att_ = att_ + 1
                if (att_ .le. noatt_ - 1) then
                    tag = attribs(1, att_)
                    data(1) = attribs(2, att_)
                    noattribs = 0
                    nodata = 1
                    endtag = .false.
                else
                    tag = starttag
                    noattribs = 0
                    nodata = 0
                    endtag = .true.
                    cycle
                end if
            else
                if (endtag_org) then
                    return
                else
                    call xml_get(info, tag, endtag, attribs, noattribs, data, nodata)
                    if (xml_error(info)) then
                        write (lurep_, *) 'Error reading input file!'
                        error = .true.
                        return
                    end if
                end if
            end if
            if (endtag .and. tag == starttag) then
                exit
            end if
            if (endtag .and. noattribs == 0) then
                if (xml_ok(info)) then
                    cycle
                else
                    exit
                end if
            end if
            select case (tag)
            case ('xs:element')
                call read_xml_type_xs_component_array( &
                    info, tag, endtag, attribs, noattribs, data, nodata, &
                    dvar%component, has_component)
            case ('comment', '!--')
                ! Simply ignore
            case default
                if (strict_) then
                    error = .true.
                    call xml_report_errors(info, &
                                           'Unknown or wrongly placed tag: '//trim(tag))
                end if
            end select
            nodata = 0
            if (.not. xml_ok(info)) exit
        end do
        if (.not. has_component) then
            has_dvar = .false.
            call xml_report_errors(info, 'Missing data on component')
        end if
    end subroutine read_xml_type_xs_choice
    subroutine init_xml_type_xs_choice_array(dvar)
        type(xs_choice), dimension(:), pointer :: dvar
        if (associated(dvar)) then
            deallocate (dvar)
        end if
        allocate (dvar(0))
    end subroutine init_xml_type_xs_choice_array
    subroutine init_xml_type_xs_choice(dvar)
        type(xs_choice) :: dvar
    end subroutine init_xml_type_xs_choice
    subroutine write_xml_type_xs_choice_array( &
        info, tag, indent, dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(in) :: tag
        integer :: indent
        type(xs_choice), dimension(:) :: dvar
        integer :: i
        do i = 1, size(dvar)
            call write_xml_type_xs_choice(info, tag, indent, dvar(i))
        end do
    end subroutine write_xml_type_xs_choice_array

    subroutine write_xml_type_xs_choice( &
        info, tag, indent, dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(in) :: tag
        integer :: indent
        type(xs_choice) :: dvar
        character(len=100) :: indentation
        indentation = ' '
        write (info%lun, '(4a)') indentation(1:min(indent, 100)), &
            '<', trim(tag), '>'
        call write_xml_type_xs_component_array(info, 'xs:element', indent + 3, dvar%component)
        write (info%lun, '(4a)') indentation(1:min(indent, 100)), &
            '</'//trim(tag)//'>'
    end subroutine write_xml_type_xs_choice

    subroutine read_xml_type_xs_complexType_array( &
        info, tag, endtag, attribs, noattribs, data, nodata, &
        dvar, has_dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(inout) :: tag
        logical, intent(inout) :: endtag
        character(len=*), dimension(:, :), intent(inout) :: attribs
        integer, intent(inout) :: noattribs
        character(len=*), dimension(:), intent(inout) :: data
        integer, intent(inout) :: nodata
        type(xs_complexType), dimension(:), pointer :: dvar
        logical, intent(inout) :: has_dvar

        integer :: newsize
        type(xs_complexType), dimension(:), pointer :: newvar

        newsize = size(dvar) + 1
        allocate (newvar(1:newsize))
        newvar(1:newsize - 1) = dvar
        deallocate (dvar)
        dvar => newvar

        call read_xml_type_xs_complexType(info, tag, endtag, attribs, noattribs, data, nodata, &
                                          dvar(newsize), has_dvar)
    end subroutine read_xml_type_xs_complexType_array

    subroutine read_xml_type_xs_complexType(info, starttag, endtag, attribs, noattribs, data, nodata, &
                                            dvar, has_dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(in) :: starttag
        logical, intent(inout) :: endtag
        character(len=*), dimension(:, :), intent(inout) :: attribs
        integer, intent(inout) :: noattribs
        character(len=*), dimension(:), intent(inout) :: data
        integer, intent(inout) :: nodata
        type(xs_complexType), intent(inout) :: dvar
        logical, intent(inout) :: has_dvar

        integer :: att_
        integer :: noatt_
        logical :: error
        logical :: endtag_org
        character(len=len(starttag)) :: tag
        logical :: has_all
        logical :: has_sequence
        logical :: has_choice
        logical :: has_simpleContent
        has_all = .false.
        has_sequence = .false.
        has_choice = .false.
        has_simpleContent = .false.
        call init_xml_type_xs_complexType(dvar)
        has_dvar = .true.
        error = .false.
        att_ = 0
        noatt_ = noattribs + 1
        endtag_org = endtag
        do
            if (nodata /= 0) then
                noattribs = 0
                tag = starttag
            elseif (att_ .lt. noatt_ .and. noatt_ .gt. 1) then
                att_ = att_ + 1
                if (att_ .le. noatt_ - 1) then
                    tag = attribs(1, att_)
                    data(1) = attribs(2, att_)
                    noattribs = 0
                    nodata = 1
                    endtag = .false.
                else
                    tag = starttag
                    noattribs = 0
                    nodata = 0
                    endtag = .true.
                    cycle
                end if
            else
                if (endtag_org) then
                    return
                else
                    call xml_get(info, tag, endtag, attribs, noattribs, data, nodata)
                    if (xml_error(info)) then
                        write (lurep_, *) 'Error reading input file!'
                        error = .true.
                        return
                    end if
                end if
            end if
            if (endtag .and. tag == starttag) then
                exit
            end if
            if (endtag .and. noattribs == 0) then
                if (xml_ok(info)) then
                    cycle
                else
                    exit
                end if
            end if
            select case (tag)
            case ('xs:all')
                call read_xml_type_xs_all( &
                    info, tag, endtag, attribs, noattribs, data, nodata, &
                    dvar%all, has_all)
            case ('xs:sequence')
                call read_xml_type_xs_sequence( &
                    info, tag, endtag, attribs, noattribs, data, nodata, &
                    dvar%sequence, has_sequence)
            case ('xs:choice')
                call read_xml_type_xs_choice( &
                    info, tag, endtag, attribs, noattribs, data, nodata, &
                    dvar%choice, has_choice)
            case ('xs:simpleContent')
                call read_xml_type_xs_simpleContent( &
                    info, tag, endtag, attribs, noattribs, data, nodata, &
                    dvar%simpleContent, has_simpleContent)
            case ('comment', '!--')
                ! Simply ignore
            case default
                if (strict_) then
                    error = .true.
                    call xml_report_errors(info, &
                                           'Unknown or wrongly placed tag: '//trim(tag))
                end if
            end select
            nodata = 0
            if (.not. xml_ok(info)) exit
        end do
    end subroutine read_xml_type_xs_complexType
    subroutine init_xml_type_xs_complexType_array(dvar)
        type(xs_complexType), dimension(:), pointer :: dvar
        if (associated(dvar)) then
            deallocate (dvar)
        end if
        allocate (dvar(0))
    end subroutine init_xml_type_xs_complexType_array
    subroutine init_xml_type_xs_complexType(dvar)
        type(xs_complexType) :: dvar
        dvar%all = xs_all(null())
        dvar%sequence = xs_sequence(null())
        dvar%choice = xs_choice(null())
        dvar%simpleContent = xs_simpleContent(xs_extension(null()))
    end subroutine init_xml_type_xs_complexType
    subroutine write_xml_type_xs_complexType_array( &
        info, tag, indent, dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(in) :: tag
        integer :: indent
        type(xs_complexType), dimension(:) :: dvar
        integer :: i
        do i = 1, size(dvar)
            call write_xml_type_xs_complexType(info, tag, indent, dvar(i))
        end do
    end subroutine write_xml_type_xs_complexType_array

    subroutine write_xml_type_xs_complexType( &
        info, tag, indent, dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(in) :: tag
        integer :: indent
        type(xs_complexType) :: dvar
        character(len=100) :: indentation
        indentation = ' '
        write (info%lun, '(4a)') indentation(1:min(indent, 100)), &
            '<', trim(tag), '>'
        call write_xml_type_xs_all(info, 'xs:all', indent + 3, dvar%all)
        call write_xml_type_xs_sequence(info, 'xs:sequence', indent + 3, dvar%sequence)
        call write_xml_type_xs_choice(info, 'xs:choice', indent + 3, dvar%choice)
        call write_xml_type_xs_simpleContent(info, 'xs:simpleContent', indent + 3, dvar%simpleContent)
        write (info%lun, '(4a)') indentation(1:min(indent, 100)), &
            '</'//trim(tag)//'>'
    end subroutine write_xml_type_xs_complexType

    subroutine read_xml_type_xs_simpleType_array( &
        info, tag, endtag, attribs, noattribs, data, nodata, &
        dvar, has_dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(inout) :: tag
        logical, intent(inout) :: endtag
        character(len=*), dimension(:, :), intent(inout) :: attribs
        integer, intent(inout) :: noattribs
        character(len=*), dimension(:), intent(inout) :: data
        integer, intent(inout) :: nodata
        type(xs_simpleType), dimension(:), pointer :: dvar
        logical, intent(inout) :: has_dvar

        integer :: newsize
        type(xs_simpleType), dimension(:), pointer :: newvar

        newsize = size(dvar) + 1
        allocate (newvar(1:newsize))
        newvar(1:newsize - 1) = dvar
        deallocate (dvar)
        dvar => newvar

        call read_xml_type_xs_simpleType(info, tag, endtag, attribs, noattribs, data, nodata, &
                                         dvar(newsize), has_dvar)
    end subroutine read_xml_type_xs_simpleType_array

    subroutine read_xml_type_xs_simpleType(info, starttag, endtag, attribs, noattribs, data, nodata, &
                                           dvar, has_dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(in) :: starttag
        logical, intent(inout) :: endtag
        character(len=*), dimension(:, :), intent(inout) :: attribs
        integer, intent(inout) :: noattribs
        character(len=*), dimension(:), intent(inout) :: data
        integer, intent(inout) :: nodata
        type(xs_simpleType), intent(inout) :: dvar
        logical, intent(inout) :: has_dvar

        integer :: att_
        integer :: noatt_
        logical :: error
        logical :: endtag_org
        character(len=len(starttag)) :: tag
        logical :: has_name
        logical :: has_restriction
        logical :: has_union
        has_name = .false.
        has_restriction = .false.
        has_union = .false.
        call init_xml_type_xs_simpleType(dvar)
        has_dvar = .true.
        error = .false.
        att_ = 0
        noatt_ = noattribs + 1
        endtag_org = endtag
        do
            if (nodata /= 0) then
                noattribs = 0
                tag = starttag
            elseif (att_ .lt. noatt_ .and. noatt_ .gt. 1) then
                att_ = att_ + 1
                if (att_ .le. noatt_ - 1) then
                    tag = attribs(1, att_)
                    data(1) = attribs(2, att_)
                    noattribs = 0
                    nodata = 1
                    endtag = .false.
                else
                    tag = starttag
                    noattribs = 0
                    nodata = 0
                    endtag = .true.
                    cycle
                end if
            else
                if (endtag_org) then
                    return
                else
                    call xml_get(info, tag, endtag, attribs, noattribs, data, nodata)
                    if (xml_error(info)) then
                        write (lurep_, *) 'Error reading input file!'
                        error = .true.
                        return
                    end if
                end if
            end if
            if (endtag .and. tag == starttag) then
                exit
            end if
            if (endtag .and. noattribs == 0) then
                if (xml_ok(info)) then
                    cycle
                else
                    exit
                end if
            end if
            select case (tag)
            case ('name')
                call read_xml_word( &
                    info, tag, endtag, attribs, noattribs, data, nodata, &
                    dvar%name, has_name)
            case ('xs:restriction')
                call read_xml_type_xs_restriction( &
                    info, tag, endtag, attribs, noattribs, data, nodata, &
                    dvar%restriction, has_restriction)
            case ('xs:union')
                call read_xml_type_xs_union( &
                    info, tag, endtag, attribs, noattribs, data, nodata, &
                    dvar%union, has_union)
            case ('comment', '!--')
                ! Simply ignore
            case default
                if (strict_) then
                    error = .true.
                    call xml_report_errors(info, &
                                           'Unknown or wrongly placed tag: '//trim(tag))
                end if
            end select
            nodata = 0
            if (.not. xml_ok(info)) exit
        end do
    end subroutine read_xml_type_xs_simpleType
    subroutine init_xml_type_xs_simpleType_array(dvar)
        type(xs_simpleType), dimension(:), pointer :: dvar
        if (associated(dvar)) then
            deallocate (dvar)
        end if
        allocate (dvar(0))
    end subroutine init_xml_type_xs_simpleType_array
    subroutine init_xml_type_xs_simpleType(dvar)
        type(xs_simpleType) :: dvar
        dvar%name = 'string'
        dvar%restriction = dummy_xs_restriction
        dvar%union = xs_union('?')
    end subroutine init_xml_type_xs_simpleType
    subroutine write_xml_type_xs_simpleType_array( &
        info, tag, indent, dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(in) :: tag
        integer :: indent
        type(xs_simpleType), dimension(:) :: dvar
        integer :: i
        do i = 1, size(dvar)
            call write_xml_type_xs_simpleType(info, tag, indent, dvar(i))
        end do
    end subroutine write_xml_type_xs_simpleType_array

    subroutine write_xml_type_xs_simpleType( &
        info, tag, indent, dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(in) :: tag
        integer :: indent
        type(xs_simpleType) :: dvar
        character(len=100) :: indentation
        indentation = ' '
        write (info%lun, '(4a)') indentation(1:min(indent, 100)), &
            '<', trim(tag), '>'
        call write_to_xml_word(info, 'name', indent + 3, dvar%name)
        call write_xml_type_xs_restriction(info, 'xs:restriction', indent + 3, dvar%restriction)
        call write_xml_type_xs_union(info, 'xs:union', indent + 3, dvar%union)
        write (info%lun, '(4a)') indentation(1:min(indent, 100)), &
            '</'//trim(tag)//'>'
    end subroutine write_xml_type_xs_simpleType

    subroutine read_xml_type_xs_element_array( &
        info, tag, endtag, attribs, noattribs, data, nodata, &
        dvar, has_dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(inout) :: tag
        logical, intent(inout) :: endtag
        character(len=*), dimension(:, :), intent(inout) :: attribs
        integer, intent(inout) :: noattribs
        character(len=*), dimension(:), intent(inout) :: data
        integer, intent(inout) :: nodata
        type(xs_element), dimension(:), pointer :: dvar
        logical, intent(inout) :: has_dvar

        integer :: newsize
        type(xs_element), dimension(:), pointer :: newvar

        newsize = size(dvar) + 1
        allocate (newvar(1:newsize))
        newvar(1:newsize - 1) = dvar
        deallocate (dvar)
        dvar => newvar

        call read_xml_type_xs_element(info, tag, endtag, attribs, noattribs, data, nodata, &
                                      dvar(newsize), has_dvar)
    end subroutine read_xml_type_xs_element_array

    subroutine read_xml_type_xs_element(info, starttag, endtag, attribs, noattribs, data, nodata, &
                                        dvar, has_dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(in) :: starttag
        logical, intent(inout) :: endtag
        character(len=*), dimension(:, :), intent(inout) :: attribs
        integer, intent(inout) :: noattribs
        character(len=*), dimension(:), intent(inout) :: data
        integer, intent(inout) :: nodata
        type(xs_element), intent(inout) :: dvar
        logical, intent(inout) :: has_dvar

        integer :: att_
        integer :: noatt_
        logical :: error
        logical :: endtag_org
        character(len=len(starttag)) :: tag
        logical :: has_name
        logical :: has_type
        logical :: has_nillable
        logical :: has_annotation
        logical :: has_complexType
        logical :: has_simpleType
        logical :: has_attribute
        has_name = .false.
        has_type = .false.
        has_nillable = .false.
        has_annotation = .false.
        has_complexType = .false.
        has_simpleType = .false.
        has_attribute = .false.
        allocate (dvar%attribute(0))
        call init_xml_type_xs_element(dvar)
        has_dvar = .true.
        error = .false.
        att_ = 0
        noatt_ = noattribs + 1
        endtag_org = endtag
        do
            if (nodata /= 0) then
                noattribs = 0
                tag = starttag
            elseif (att_ .lt. noatt_ .and. noatt_ .gt. 1) then
                att_ = att_ + 1
                if (att_ .le. noatt_ - 1) then
                    tag = attribs(1, att_)
                    data(1) = attribs(2, att_)
                    noattribs = 0
                    nodata = 1
                    endtag = .false.
                else
                    tag = starttag
                    noattribs = 0
                    nodata = 0
                    endtag = .true.
                    cycle
                end if
            else
                if (endtag_org) then
                    return
                else
                    call xml_get(info, tag, endtag, attribs, noattribs, data, nodata)
                    if (xml_error(info)) then
                        write (lurep_, *) 'Error reading input file!'
                        error = .true.
                        return
                    end if
                end if
            end if
            if (endtag .and. tag == starttag) then
                exit
            end if
            if (endtag .and. noattribs == 0) then
                if (xml_ok(info)) then
                    cycle
                else
                    exit
                end if
            end if
            select case (tag)
            case ('name')
                call read_xml_word( &
                    info, tag, endtag, attribs, noattribs, data, nodata, &
                    dvar%name, has_name)
            case ('type')
                call read_xml_word( &
                    info, tag, endtag, attribs, noattribs, data, nodata, &
                    dvar%type, has_type)
            case ('nillable')
                call read_xml_logical( &
                    info, tag, endtag, attribs, noattribs, data, nodata, &
                    dvar%nillable, has_nillable)
            case ('xs:annotation')
                call read_xml_type_xs_annotation( &
                    info, tag, endtag, attribs, noattribs, data, nodata, &
                    dvar%annotation, has_annotation)
            case ('xs:complexType')
                call read_xml_type_xs_complexType( &
                    info, tag, endtag, attribs, noattribs, data, nodata, &
                    dvar%complexType, has_complexType)
            case ('xs:simpleType')
                call read_xml_type_xs_simpleType( &
                    info, tag, endtag, attribs, noattribs, data, nodata, &
                    dvar%simpleType, has_simpleType)
            case ('xs:attribute')
                call read_xml_type_xs_attribute_array( &
                    info, tag, endtag, attribs, noattribs, data, nodata, &
                    dvar%attribute, has_attribute)
            case ('comment', '!--')
                ! Simply ignore
            case default
                if (strict_) then
                    error = .true.
                    call xml_report_errors(info, &
                                           'Unknown or wrongly placed tag: '//trim(tag))
                end if
            end select
            nodata = 0
            if (.not. xml_ok(info)) exit
        end do
        if (.not. has_name) then
            has_dvar = .false.
            call xml_report_errors(info, 'Missing data on name')
        end if
    end subroutine read_xml_type_xs_element
    subroutine init_xml_type_xs_element_array(dvar)
        type(xs_element), dimension(:), pointer :: dvar
        if (associated(dvar)) then
            deallocate (dvar)
        end if
        allocate (dvar(0))
    end subroutine init_xml_type_xs_element_array
    subroutine init_xml_type_xs_element(dvar)
        type(xs_element) :: dvar
        dvar%type = 'element'
        dvar%nillable = .false.
        dvar%annotation = xs_annotation(null())
        dvar%complexType = dummy_xs_complexType
        dvar%simpleType = dummy_xs_simpleType
        dvar%attribute = xs_attribute('?', '?', '?')
    end subroutine init_xml_type_xs_element
    subroutine write_xml_type_xs_element_array( &
        info, tag, indent, dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(in) :: tag
        integer :: indent
        type(xs_element), dimension(:) :: dvar
        integer :: i
        do i = 1, size(dvar)
            call write_xml_type_xs_element(info, tag, indent, dvar(i))
        end do
    end subroutine write_xml_type_xs_element_array

    subroutine write_xml_type_xs_element( &
        info, tag, indent, dvar)
        type(XML_PARSE) :: info
        character(len=*), intent(in) :: tag
        integer :: indent
        type(xs_element) :: dvar
        character(len=100) :: indentation
        indentation = ' '
        write (info%lun, '(4a)') indentation(1:min(indent, 100)), &
            '<', trim(tag), '>'
        call write_to_xml_word(info, 'name', indent + 3, dvar%name)
        call write_to_xml_word(info, 'type', indent + 3, dvar%type)
        call write_to_xml_logical(info, 'nillable', indent + 3, dvar%nillable)
        call write_xml_type_xs_annotation(info, 'xs:annotation', indent + 3, dvar%annotation)
        call write_xml_type_xs_complexType(info, 'xs:complexType', indent + 3, dvar%complexType)
        call write_xml_type_xs_simpleType(info, 'xs:simpleType', indent + 3, dvar%simpleType)
        call write_xml_type_xs_attribute_array(info, 'xs:attribute', indent + 3, dvar%attribute)
        write (info%lun, '(4a)') indentation(1:min(indent, 100)), &
            '</'//trim(tag)//'>'
    end subroutine write_xml_type_xs_element

    subroutine read_xml_file_readxsd(fname, lurep, errout)
        character(len=*), intent(in) :: fname
        integer, intent(in), optional :: lurep
        logical, intent(out), optional :: errout

        type(XML_PARSE) :: info
        logical :: error
        character(len=80) :: tag
        character(len=80) :: starttag
        logical :: endtag
        character(len=80), dimension(1:2, 1:20) :: attribs
        integer :: noattribs
        character(len=200), dimension(1:100) :: data
        integer :: nodata
        logical :: has_element
        logical :: has_simple_element
        has_element = .false.
        allocate (element(0))
        has_simple_element = .false.
        allocate (simple_element(0))

        call init_xml_file_readxsd
        call xml_open(info, fname, .true.)
        call xml_options(info, report_errors=.true., ignore_whitespace=.true.)
        lurep_ = 0
        if (present(lurep)) then
            lurep_ = lurep
            call xml_options(info, report_lun=lurep)
        end if
        do
            call xml_get(info, starttag, endtag, attribs, noattribs, &
                         data, nodata)
            if (starttag /= '!--') exit
        end do
        if (starttag /= "xs:schema") then
            call xml_report_errors(info, &
                                   'XML-file should have root element "xs:schema"')
            error = .true.
            call xml_close(info)
            return
        end if
        strict_ = .false.
        error = .false.
        do
            call xml_get(info, tag, endtag, attribs, noattribs, data, nodata)
            if (xml_error(info)) then
                write (lurep_, *) 'Error reading input file!'
                error = .true.
                return
            end if
            if (endtag .and. tag == starttag) then
                exit
            end if
            if (endtag .and. noattribs == 0) then
                if (xml_ok(info)) then
                    cycle
                else
                    exit
                end if
            end if
            select case (tag)
            case ('xs:element')
                call read_xml_type_xs_element_array( &
                    info, tag, endtag, attribs, noattribs, data, nodata, &
                    element, has_element)
            case ('xs:simpleType')
                call read_xml_type_xs_simpleType_array( &
                    info, tag, endtag, attribs, noattribs, data, nodata, &
                    simple_element, has_simple_element)
            case ('comment', '!--')
                ! Simply ignore
            case default
                if (strict_) then
                    error = .true.
                    call xml_report_errors(info, &
                                           'Unknown or wrongly placed tag: '//trim(tag))
                end if
            end select
            nodata = 0
            if (.not. xml_ok(info)) exit
        end do
        if (.not. has_element) then
            error = .true.
            call xml_report_errors(info, 'Missing data on element')
        end if
        if (.not. has_simple_element) then
            error = .true.
            call xml_report_errors(info, 'Missing data on simple_element')
        end if
        if (present(errout)) errout = error
    end subroutine

    subroutine write_xml_file_readxsd(fname, lurep)
        character(len=*), intent(in) :: fname
        integer, intent(in), optional :: lurep

        type(XML_PARSE) :: info
        integer :: indent = 0

        call xml_open(info, fname, .false.)
        call xml_options(info, report_errors=.true.)
        if (present(lurep)) then
            call xml_options(info, report_errors=.true.)
        end if
        write (info%lun, '(a)') &
            '<xs:schema>'
        call write_xml_type_xs_element_array(info, 'xs:element', indent + 3, element)
        call write_xml_type_xs_simpleType_array(info, 'xs:simpleType', indent + 3, simple_element)
        write (info%lun, '(a)') '</xs:schema>'
        call xml_close(info)
    end subroutine

    subroutine init_xml_file_readxsd

    end subroutine

end module
